/*****************************************************************
 * Copyright (C) Gasgoo Corporation. All rights reserved.
 * 
 * Author:   Jack Jiang
 * Create Date:  08/26/2006
 * Usage:
 *
 * RevisionHistory
 * Date         Author               Description
 * 
*****************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Security.Permissions;

using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;

using ZJFramework.Data;

namespace ZJFramework.DataAccess {
    internal static class DatabaseManager {
        private static Dictionary<string, Database> s_DatabaseHashtable;
        private static FileSystemWatcher s_Watcher;
        private static FileSystemChangeEventHandler s_FileChangeHandler;

        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
        static DatabaseManager() {
            s_DatabaseHashtable = new Dictionary<string, Database>();
            s_FileChangeHandler = new FileSystemChangeEventHandler(500);
            s_FileChangeHandler.ActualHandler += new FileSystemEventHandler(OnFileChanged);

            // set up file system watcher
            string databaseFolder = Path.GetDirectoryName(DataAccessSetting.DatabaseConfigFile);
            string databaseFile = Path.GetFileName(DataAccessSetting.DatabaseConfigFile);
            s_Watcher = new FileSystemWatcher(databaseFolder);
            s_Watcher.Filter = databaseFile;
            s_Watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.CreationTime;
            s_Watcher.Changed += new FileSystemEventHandler(s_FileChangeHandler.ChangeEventHandler);
            s_Watcher.EnableRaisingEvents = true;

            // load database
            s_DatabaseHashtable = LoadDatabaseList();
        }

        private static void OnFileChanged(Object sender, FileSystemEventArgs e) {
            //DataAccessLogger.LogDatabaseFileChanged(e);
            s_DatabaseHashtable = LoadDatabaseList();
        }

        private static Dictionary<string, Database> LoadDatabaseList() {
            DatabaseList list = ObjectXmlSerializer.LoadFromXml<DatabaseList>(DataAccessSetting.DatabaseConfigFile);
            if (list == null || list.DatabaseInstances == null || list.DatabaseInstances.Length == 0) {
                throw new DatabaseNotSpecifiedException();
            }
            // convert DatabaseList to a hashtable
            Dictionary<string, Database> hashtable = new Dictionary<string, Database>(list.DatabaseInstances.Length);
            foreach (DatabaseInstance instance in list.DatabaseInstances) {
                SqlDatabase db = new SqlDatabase(instance.ConnectionString);
                hashtable.Add(instance.Name.ToUpper(), db);
            }

            //DataAccessLogger.LogDatabaseFileLoaded(DataAccessSetting.DatabaseConfigFile);

            return hashtable;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name">name of the database, case insensitive</param>
        /// <returns></returns>
        /// <exception cref="KeyNotFoundException">The name is not found in the database list.</exception>
        public static Database GetDatabase(string name) {
            return s_DatabaseHashtable[name.ToUpper()];
        }
    }
}
